package com.infolab.aims.web;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;

import com.infolab.aims.common.AbstractController;
import com.infolab.aims.common.bean.SearchCriteria;
import com.infolab.aims.common.bean.SearchResult;
import com.infolab.aims.common.exception.ResourceNotFoundException;

import com.infolab.aims.domain.Vendor;
import com.infolab.aims.domain.VendorAsset;
import com.infolab.aims.domain.asset.AssetModel;

import com.infolab.aims.service.intf.AssetModelService;
import com.infolab.aims.service.intf.VendorService;


@Controller
@RequestMapping("/vendor")
@SessionAttributes(value=VendorController.SESSION_SEARCH_CRITERIA)
public class VendorController extends AbstractController {

	public static final String SESSION_SEARCH_CRITERIA ="searchCriteria";
	public static final String CONTEXT_PATH ="/vendor";
	public static final String JSP_MAIN_FORM="vendorForm";
	public static final String JSP_VENDOR_ASSET_FORM="vendorAssetForm";
	public static final String JSP_VENDOR_ASSET_FORM_POPUP="vendorAssetFormPopUp";
	public static final String JSP_MAIN_SEARCH="vendorSearch";

	@Autowired
	VendorService vendorService;
	
	@Autowired
	AssetModelService assetModelService;

	@RequestMapping(value="create", method = RequestMethod.GET)
	public String createVendor(Model model) {

		Vendor vendor = new Vendor();
		
		model.addAttribute(vendor);
		
		
		return JSP_MAIN_FORM;
	}

	@RequestMapping(value="create",method=RequestMethod.POST)
	public String saveVendor(@ModelAttribute Vendor vendor, BindingResult result,Model model,HttpServletRequest request) {

		
		if (validateVendor(vendor, result)) {	
			return JSP_MAIN_FORM;
		}
		
		vendor.setCreatedBy(getCurrentUserName(request));
		
		vendorService.createVendor(vendor);
		setSuccessMessage(getMessageResources("success.create","vendor " + vendor.getVendorName()));

		refreshGlobalVendor(request);

		return "redirect:"+CONTEXT_PATH+"/update/" + vendor.getVendorId();


	}

	@RequestMapping(value="update/{id}",method=RequestMethod.POST)
	public String updateVendor(@PathVariable Integer id,@ModelAttribute Vendor vendor, BindingResult result,Model model,HttpServletRequest request) {

		if (validateVendor(vendor, result)) {
			return JSP_MAIN_FORM;
		}
		
		vendor.setModifiedBy(getCurrentUserName(request));

		vendorService.updateVendor(vendor);
		setSuccessMessage(getMessageResources("success.update","vendor " + vendor.getVendorName()));

		refreshGlobalVendor(request);

		return "redirect:"+CONTEXT_PATH+"/update/" + vendor.getVendorId();	

	}

	@RequestMapping(value={"update/{id}","detail/{id}"}, method = RequestMethod.GET)
	public String detailVendor(@PathVariable Integer id,Model model,HttpServletRequest request) {

		Vendor vendor = vendorService.getVendor(id);
		if(vendor==null) {
			throw new ResourceNotFoundException("Vendor " + id);
		}

		model.addAttribute(vendor);
		return JSP_MAIN_FORM;

	}

	@RequestMapping(value={"updateAssets/{id}"}, method = RequestMethod.GET)
	public String detailAssets(@PathVariable Integer id,Model model,HttpServletRequest request) {

		Vendor vendor = vendorService.getVendor(id);
		if(vendor==null) {
			throw new ResourceNotFoundException("Vendor " + id);
		}
		populateVendor(model);
		model.addAttribute(vendor);
		
		
		
		String popUp = request.getParameter("popUpFlag")!=null? (String)request.getParameter("popUpFlag"):"";
		if(popUp.equalsIgnoreCase("Y")){
			model.addAttribute("popUpFlag","Y");
			return JSP_VENDOR_ASSET_FORM_POPUP;
		}
		else{
			return JSP_VENDOR_ASSET_FORM;
		}

		
	}

	@RequestMapping(value={"updateAssets/{id}"}, method = RequestMethod.POST)
	public String updateAssets(@PathVariable Integer id,@ModelAttribute Vendor vendor, BindingResult result,Model model,HttpServletRequest request) {

		
		populateVendor(model);
		model.addAttribute(vendor);
		
		String target;		
		String popUp = request.getParameter("popUpFlag")!=null? (String)request.getParameter("popUpFlag"):"";
		if(popUp.equalsIgnoreCase("Y")){
			model.addAttribute("popUpFlag","Y");
			target =  JSP_VENDOR_ASSET_FORM_POPUP;
		}
		else{
			target =  JSP_VENDOR_ASSET_FORM;
		}
		
		if (validateVendorAssets(vendor, result)) {			
				return target;
		}
			
		vendor.setModifiedBy(getCurrentSystemPersonName(request));

		prepareAuditObjectForUpdateAssets(vendor, request);
		vendorService.updateVendorAssets(vendor);
		
		setSuccessMessage(getMessageResources("success.update","vendor assets"));

		return "redirect:"+CONTEXT_PATH+"/updateAssets/" + vendor.getVendorId();	

	}

	@InitBinder
	public void initBinder(WebDataBinder binder) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		dateFormat.setLenient(false);
		binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
	}


	@ModelAttribute(VendorController.SESSION_SEARCH_CRITERIA)
	public SearchCriteria getVendorSearchCriteria()
	{
		return new SearchCriteria();
	}


	@RequestMapping(value="search")
	public String searchVendor(@ModelAttribute(VendorController.SESSION_SEARCH_CRITERIA) SearchCriteria searchCriteria,@ModelAttribute("currentSearchCriteria") SearchCriteria currentSearchCriteria,Model model) {

		if(currentSearchCriteria.getCurPage()!=null)
			searchCriteria.setCurPage(currentSearchCriteria.getCurPage());

		searchCriteria.addSearchCriteria("active", true);

		SearchResult searchResult = vendorService.searchVendor(searchCriteria);
		model.addAttribute(searchResult);

		return JSP_MAIN_SEARCH;
	}

	@RequestMapping(value={"delete/{id}"}, method = RequestMethod.GET)
	public String deleteVendor(@PathVariable Integer id,Model model,HttpServletRequest request) {

		Vendor vendor = vendorService.getVendor(id);
		vendor.setModifiedBy(getCurrentUserName(request));
		vendorService.deleteVendor(vendor);

		refreshGlobalVendor(request);

		return "redirect:"+CONTEXT_PATH+"/search";
	}


	private boolean validateVendor(Vendor vendor,BindingResult result)
	{
		//		if(vendor.getSection().getSectionId()==null)
		//			vendor.setSection(null);

		validator.validate(vendor, result);

		return result.hasErrors();
	}

	private boolean validateVendorAssets(Vendor vendor,BindingResult result)
	{
		List<VendorAsset> vendorAssets= vendor.getVendorAssets();
		
		for(int i=0;i<vendorAssets.size();i++)
		{
			VendorAsset vendorAsset = vendorAssets.get(i);
			if(vendorAsset.getAssetModel()==null || vendorAsset.getAssetModel().getAssetModelId()==null)
				result.reject("error.empty.param", new String[]{"Asset Model on row "+(i+1)}, "");
		}
		return result.hasErrors();
	}
	
	public void populateVendor(Model model) {
		SearchCriteria searchCriteria = new SearchCriteria();
		searchCriteria.addSearchCriteria("active", true);
		List<AssetModel> assetModels = assetModelService.findAssetModels(searchCriteria);
		model.addAttribute(assetModels);
	}
	
	private void prepareAuditObjectForUpdateAssets(Vendor vendor, HttpServletRequest request){
			if(vendor.getVendorId()!=null){
				Vendor tmp = findVendor(request, vendor.getVendorId());
				vendor.setVendorName(tmp.getVendorName());
				vendor.setVendorType(tmp.getVendorType());
			}
			
		
	}

	
}
